﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

namespace OmniKits.Windows.Design
{
    public class ResizeThumb : Thumb
    {
        public ResizeThumb()
        {
            this.DragDelta += OnDragDelta;
        }

        protected virtual void OnDragDelta(object sender, DragDeltaEventArgs e)
        {
            var target = this.DataContext as FrameworkElement;
            if (target == null) return;

            double x = 0, y = 0, tmp;
            var margin = target.Margin;

            switch (this.VerticalAlignment)
            {
                case VerticalAlignment.Top:
                    tmp = target.ActualHeight - e.VerticalChange;

                    if (tmp > target.MaxHeight)
                        tmp = target.MaxHeight;
                    else if (tmp < target.MinHeight)
                        tmp = target.MinHeight;

                    y = target.ActualHeight - tmp;
                    target.Height = tmp;

                    tmp = Canvas.GetTop(target);
                    if (double.IsNaN(tmp))
                    {
                        if (double.IsNaN(Canvas.GetBottom(target)))
                            margin.Top += y;
                    }
                    else
                    {
                        Canvas.SetTop(target, tmp + y);
                    }
                    break;
                case VerticalAlignment.Bottom:
                    tmp = target.ActualHeight + e.VerticalChange;

                    if (tmp > target.MaxHeight)
                        tmp = target.MaxHeight;
                    else if (tmp < target.MinHeight)
                        tmp = target.MinHeight;

                    y = tmp - target.ActualHeight;
                    target.Height = tmp;

                    tmp = Canvas.GetBottom(target);
                    if (double.IsNaN(tmp))
                    {
                        if (double.IsNaN(Canvas.GetTop(target)))
                            margin.Bottom -= y;
                    }
                    else
                    {
                        Canvas.SetBottom(target, tmp - y);
                    }
                    break;
            }

            switch (this.HorizontalAlignment)
            {
                case HorizontalAlignment.Left:
                    tmp = target.ActualWidth - e.HorizontalChange;

                    if (tmp > target.MaxWidth)
                        tmp = target.MaxWidth;
                    else if (tmp < target.MinWidth)
                        tmp = target.MinWidth;

                    x = target.ActualWidth - tmp;
                    target.Width = tmp;

                    tmp = Canvas.GetLeft(target);
                    if (double.IsNaN(tmp))
                    {
                        if (double.IsNaN(Canvas.GetRight(target)))
                            margin.Left += x;
                    }
                    else
                    {
                        Canvas.SetLeft(target, tmp + x);
                    }
                    break;
                case HorizontalAlignment.Right:
                    tmp = target.ActualWidth + e.HorizontalChange;

                    if (tmp > target.MaxWidth)
                        tmp = target.MaxWidth;
                    else if (tmp < target.MinWidth)
                        tmp = target.MinWidth;

                    x = tmp - target.ActualWidth;
                    target.Width = tmp;

                    tmp = Canvas.GetRight(target);
                    if (double.IsNaN(tmp))
                    {
                        if (double.IsNaN(Canvas.GetLeft(target)))
                            margin.Right -= x;
                    }
                    else
                    {
                        Canvas.SetRight(target, tmp - x);
                    }
                    break;
            }

            target.Margin = margin;

            e.Handled = true;
        }
    }
}
